package com.bdqn.ch06.SL;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

import java.util.Arrays;

/**
 * UserServiceLogger  示例27  使用注解实现 Spring AOP
 * @aurhor Administrator  whs
 * @since 2024/7/17
 *
 * @Aspect 注解的作用是将 UserServiceLogger 类定义为切面
 *
 * @Before 注解的作用是将 before() 方法定义为前置增强
 *
 * @AfterReturning 注解的作用是将 afterReturning() 方法定义为后置增强 增强方法中使用了 JoinPoint 类型的参数，以获得当前 连接点的信息
 * 后置增强 还可以定义一个参数，用于接收 目标方法的返回值 。
 */

@Aspect
public class UserServiceLogger {

    private static final Logger logger = Logger.getLogger(UserServiceLogger.class);


    /**
     *
     * @Pointcut 注解用来 声明切入点的表达式
     * 此方法的返回值必须是void类型
     */
    @Pointcut("execution(* com.bdqn.ch05.SL.Service.impl.UserServiceImpl.*(..))")
    public void pointcut(){}



    /**
     * 前置增强
     * @param jp 增强方法中使用了 JoinPoint 类型的参数，以获得当前 连接点的信息
     */
    @Before("execution(* com.bdqn.ch05.SL.Service.impl.UserServiceImpl.*(..))")
    public void before(JoinPoint jp) {
        logger.info("调用 "+jp.getTarget()+" 的" + jp.getSignature().getName()+ " 方法。方法入参： "+ Arrays.toString(jp.getArgs()));
    }

    /**
     * 后置增强
     * @param jp 增强方法中使用了 JoinPoint 类型的参数，以获得当前 连接点的信息
     * @param returnValue  目标方法的返回值
     * 需要注意的是，必须 在 @AfterReturning 注解中通过 returning属性指定该参数的名称，Spring框架才会将目标方法的返回值 赋值给指定名称的参数
     */
    @AfterReturning(pointcut = "execution(* com.bdqn.ch05.SL.Service.impl.UserServiceImpl.*(..))",returning = "returnValue")
    public void afterReturning(JoinPoint jp, Object returnValue) {
        logger.info("调用 "+jp.getTarget()+" 的" + jp.getSignature().getName()+ " 方法。方法入参： "+  returnValue);
    }


}
